{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 第三章.分治算法\n",
    "## 二分查找\n",
    "<p>分解:首先将拍好序的数组分为两组.治理:将中间的元素mid与查找元素x比较,如果mid=x则返回mid的位置,算法结束.如果x>mid,则在右半段查找。如果x 小于 mid，则在左半段查找</p>"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "list[3]=8\n"
     ]
    }
   ],
   "source": [
    "def binary_search(lis,left,right,num):\n",
    "    if left > right: # 递归结束条件\n",
    "        return -1\n",
    "    mid = (left+right)//2\n",
    "    if num <lis[mid]:\n",
    "        return binary_search(lis,left,mid-1,num)\n",
    "    elif num >lis[mid]:\n",
    "        return binary_search(lis,mid+1,right,num)\n",
    "    else:\n",
    "        return mid\n",
    "\n",
    "list = [11,32,51,21,42,9,5,6,7,8]\n",
    "list.sort()\n",
    "left = 0\n",
    "right =len(list) -1\n",
    "num = 8\n",
    "res = binary_search(list,left,right,num)\n",
    "print('list['+str(res)+']='+str(num))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-09-27T01:09:26.420921600Z",
     "start_time": "2023-09-27T01:09:26.409925600Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 寻找第二大的元素"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最大值淘汰的元素为: [18, 87, 54, 12]\n",
      "第二大的元素: 87\n"
     ]
    }
   ],
   "source": [
    "def find_max(a_list,left,right):\n",
    "    global dic\n",
    "    if left >=right:\n",
    "        return a_list[left]\n",
    "    mid = (left+right)//2\n",
    "    left_max = find_max(a_list,left,mid)\n",
    "    right_max = find_max(a_list,mid+1,right)\n",
    "    if left_max > right_max:\n",
    "        dic[left_max].append(right_max)\n",
    "        return left_max\n",
    "    else:\n",
    "        dic[right_max].append(left_max)\n",
    "        return right_max\n",
    "\n",
    "def find_second(n_max):\n",
    "    n =len(n_max)\n",
    "    second_max = n_max[0]\n",
    "    for i in range(1,n):\n",
    "        if n_max[i] > second_max:\n",
    "            second_max = n_max[i]\n",
    "    return second_max\n",
    "\n",
    "\n",
    "a_list = [6,12,3,7,2,18,90,87,54,23]\n",
    "n = len(a_list)\n",
    "dic = {}\n",
    "for i in range(n):\n",
    "    dic.update([(a_list[i],[])]) # 初始化字典列表\n",
    "first_max = find_max(a_list,0,n-1)\n",
    "second_max = find_second(dic[first_max])\n",
    "print(\"最大值淘汰的元素为:\",dic[first_max])\n",
    "print('第二大的元素:',second_max)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-09-27T06:47:26.758242400Z",
     "start_time": "2023-09-27T06:47:26.702250700Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 3.4.循环赛日程表\n",
    "<p>主要解决n=2^k个运动员比赛的问题。需满足以下条件:</p>\n",
    "<ol>\n",
    "<li>每个运动员必须与剩下的n-1个运动员比赛</li>\n",
    "<li>每个选手一天只比赛一场</li>\n",
    "<li>循环赛一共进行n-1天</li>\n",
    "</ol>\n",
    "<p>算法设计思路为:分支:首先将n个运动员分解到两两一组。治理:每组两两对打，向上合并</p>"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16]\n",
      " [ 2  1  4  3  6  5  8  7 10  9 12 11 14 13 16 15]\n",
      " [ 3  4  1  2  7  8  5  6 11 12  9 10 15 16 13 14]\n",
      " [ 4  3  2  1  8  7  6  5 12 11 10  9 16 15 14 13]\n",
      " [ 5  6  7  8  1  2  3  4 13 14 15 16  9 10 11 12]\n",
      " [ 6  5  8  7  2  1  4  3 14 13 16 15 10  9 12 11]\n",
      " [ 7  8  5  6  3  4  1  2 15 16 13 14 11 12  9 10]\n",
      " [ 8  7  6  5  4  3  2  1 16 15 14 13 12 11 10  9]\n",
      " [ 9 10 11 12 13 14 15 16  1  2  3  4  5  6  7  8]\n",
      " [10  9 12 11 14 13 16 15  2  1  4  3  6  5  8  7]\n",
      " [11 12  9 10 15 16 13 14  3  4  1  2  7  8  5  6]\n",
      " [12 11 10  9 16 15 14 13  4  3  2  1  8  7  6  5]\n",
      " [13 14 15 16  9 10 11 12  5  6  7  8  1  2  3  4]\n",
      " [14 13 16 15 10  9 12 11  6  5  8  7  2  1  4  3]\n",
      " [15 16 13 14 11 12  9 10  7  8  5  6  3  4  1  2]\n",
      " [16 15 14 13 12 11 10  9  8  7  6  5  4  3  2  1]]\n"
     ]
    }
   ],
   "source": [
    "def arrange(p,q,n,arr):\n",
    "    if(n>1): # 规模大于1时,分解\n",
    "        arrange(p,q,n//2,arr) # 递归解决子问题\n",
    "        arrange(p,q+n//2,n//2,arr) # 递归解决子问题\n",
    "        # 两组对打\n",
    "        # 填左下角\n",
    "        for i in range(p+n//2,p+n):\n",
    "            for j in range(q,q+n//2):\n",
    "                arr[i][j] = arr[i-n//2][j+n//2]\n",
    "        # 填右下角\n",
    "        for i in range(p+n//2,p+n):\n",
    "            for j in range(q+n//2,q+n):\n",
    "                arr[i][j] = arr[i-n//2][j-n//2]\n",
    "\n",
    "        return arr\n",
    "\n",
    "\n",
    "import numpy as np\n",
    "k = 4\n",
    "n =2**k\n",
    "arr = np.zeros((n,n),dtype=int)\n",
    "for i in range(n):\n",
    "    arr[0][i] = i+1\n",
    "arrange(0,0,n,arr)\n",
    "print(arr)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2023-09-27T08:06:49.615135300Z",
     "start_time": "2023-09-27T08:06:44.262142600Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
